use std::fs;
use std::path::PathBuf;

use reqwest::header::HeaderValue;

use crate::components;
use crate::models::models::components::v2ray::info::ComponentV2rayState;
use crate::runtime::error::MagicBoxError;
use crate::runtime::io;
use crate::runtime::response::{Code, MagicBoxResponse};
use crate::runtime::result::MagicBoxResult;

#[tauri::command(rename_all = "snake_case")]
pub(crate) async fn invoke_component_v2ray_install(name: String, url: String, reinstall: bool) -> MagicBoxResult<MagicBoxResponse<()>> {
    log::debug!("下载V2ray-Core: {} -> {}", name.as_str(), url.as_str());
    let v2ray_path = components::v2ray::manager::manager().install_path()?;

    if v2ray_path.exists() {
        if !reinstall {
            return Ok(MagicBoxResponse::new_empty_success());
        }

        components::v2ray::manager::manager().installing(ComponentV2rayState::Installing, "移除旧版本", 0);
        let result = fs::remove_dir_all(v2ray_path.as_path());
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("移除旧版本失败: {}", err.as_str());
            components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, "安装失败: 无法移除旧版本", 0);

            return Err(MagicBoxError::new(Code::IoError, format!("移除旧版本失败: {}", err.as_str()).as_str()));
        }
    }

    components::v2ray::manager::manager().installing(ComponentV2rayState::Installing, "创建应用目录", 0);
    let result = fs::create_dir_all(v2ray_path.as_path());
    if result.is_err() {
        let err = result.unwrap_err().to_string();
        log::error!("创建目录失败: {}", err.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, "安装失败: 无法创建应用目录", 0);

        return Err(MagicBoxError::new(Code::IoError, format!("创建目录失败: {}", err.as_str()).as_str()));
    }

    // 下载文件
    components::v2ray::manager::manager().installing(ComponentV2rayState::Installing, "下载安装包(建立网络连接)", 0);
    let response = reqwest::Client::new().get(url).header("User-Agent", HeaderValue::from_str("request").unwrap()).send().await;
    if response.is_err() {
        let err = response.unwrap_err().to_string();
        log::error!("网络错误，无法下载V2ray-Core: {}", err.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法下载V2ray-Core - {}", err.as_str()).as_str(), 0);

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载V2fly-Core: {}", err.as_str()).as_str()));
    }

    let mut response = response.unwrap();
    if !response.status().is_success() {
        let status = response.status();
        log::error!("网络错误，无法下载V2ray-Core: {}", status.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法下载V2ray-Core - {}", status.as_str()).as_str(), 0);

        return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载V2fly-Core: {}", status.as_str()).as_str()));
    }

    let mut count = 0u64;
    let total = response.content_length().unwrap();
    let mut file_bytes: Vec<u8> = Vec::new();

    components::v2ray::manager::manager().installing(ComponentV2rayState::Installing, "下载安装包(传输中)", 0);
    loop {
        let bytes = response.chunk().await;
        if bytes.is_err() {
            let err = bytes.unwrap_err().to_string();
            log::error!("网络错误，无法下载V2ray-Core: {}", err.as_str());
            components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法下载V2ray-Core - {}", err.as_str()).as_str(), 0);

            return Err(MagicBoxError::new(Code::NetworkError, format!("网络错误，无法下载V2fly-Core: {}", err.as_str()).as_str()));
        }

        let bytes = bytes.unwrap();
        if bytes.is_none() {
            break;
        }

        let bytes = bytes.unwrap();
        count += bytes.len() as u64;
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, "下载安装包(传输中)", count / total);
        
        file_bytes.extend_from_slice(&bytes);
    }

    let zip_path = io::data_path(PathBuf::new().join(name))?;

    // 保存下载的压缩包
    components::v2ray::manager::manager().installing(ComponentV2rayState::Installing, "解压安装包", 100);
    let result = fs::write(zip_path.as_path(), file_bytes.as_slice());
    if result.is_err() {
        let err = result.unwrap_err().to_string();
        log::error!("写入ZIP文件失败: {}", err.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法保存安装包 - {}", err.as_str()).as_str(), 0);

        return Err(MagicBoxError::new(Code::IoError, format!("写入ZIP文件失败: {}", err.as_str()).as_str()));
    }

    let zip = fs::File::open(zip_path.as_path());
    if zip.is_err() {
        let err = zip.unwrap_err().to_string();
        log::error!("打开ZIP文件失败: {}", err.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法打开安装包 - {}", err.as_str()).as_str(), 0);

        return Err(MagicBoxError::new(Code::IoError, format!("打开ZIP文件失败: {}", err.as_str()).as_str()));
    }

    // 解压
    let result = io::unzip_file(v2ray_path.clone(), zip.unwrap());
    if result.is_err() {
        let err = result.unwrap_err().to_string();
        log::error!("解压ZIP文件失败: {}", err.as_str());
        components::v2ray::manager::manager().installing(ComponentV2rayState::InstallFailed, format!("安装失败: 无法解压安装包 - {}", err.as_str()).as_str(), 0);

        return Err(MagicBoxError::new(Code::IoError, format!("解压ZIP文件失败: {}", err.as_str()).as_str()));
    }

    components::v2ray::manager::manager().installing(ComponentV2rayState::NotRunning, "安装完成", 100);

    Ok(MagicBoxResponse::new_empty_success())
}